#include "constants.h";

XfMissionChapterExecute={
	private ["_chapter_succeeded"];
	diag_log "";
	diag_log "=========================================================================";
	diag_log "                             CHAPTER 1                                   ";
	diag_log "=========================================================================";
	diag_log "";
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Starting Chapter","_last_random_reinforcement","_random_reinf_diff","_reinforcement_power"];
	DM_Mission_Chapter_CanRun = True;
	DM_Mission_Chapter_Runs = True;
	DM_Mission_Chapter_Success = 0;
	call XfMissionChapterSetup;
	_chapter_succeeded = false;
	if (!DM_Mission_Mission_CanRun) exitWith {diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Mission canceled!"];};
	
	private ["_grp_cnt","_fnc_checkgroup","_start_time","_spawning_positions","_spawning_roads"];
	
	// We need the castle infos to send paras to the right place :)
	_random_town = DM_Chapter_Location;
	_random_town_pos = _random_town select XF_MAP_LOCATION_CENTER;
	_random_town_size = _random_town select XF_MAP_LOCATION_SIZE;
	_random_town_name = _random_town select XF_MAP_LOCATION_DISPLAYNAME;
	if (_random_town_size < 200) then { _random_town_size = 200; };
	_building = DM_Target;
	_surrounding_buildings = DM_Chapter_Data;
	

	diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Entering the loop",[_attackers, count _surrounding_buildings], Time];
	while {DM_Mission_Chapter_CanRun AND DM_Mission_Mission_CanRun} do {
		sleep 10;
		_enemy_count = ([getPos _building,400,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
		_players_in_town = [];
		if (X_MP) then {
			{
				if (isPlayer _x) then {
					if ([getPos _x, getPos _building, _random_town_size * 2] call XfPointInCircle) then { _players_in_town set [count _players_in_town, _x]};
					if ((_x distance (getPos _building)) < 100) then { _players_near_building = true; };
				};
			} foreach playableUnits;
		} else {
			if ([getPos player, getPos _building, _random_town_size * 2] call XfPointInCircle) then { _players_in_town set [count _players_in_town, player] };
			if ((player distance (getPos _building)) < 100) then { _players_near_building = true; };
		};
		
		_building_destroyed = !alive _building;
		
		if (_players_near_building && !_players_near_building_updated) then {
			_players_near_building_updated = true;
			"STR_MF_M_NEWSNETWORK_STARTED" call XfMissionMessageToAll;
			
			_spawning_positions = [];
			{
				_spawning_positions = [_spawning_positions, ([_x,"HIDE", false] call XfBuildingPosArrayASL)] call XfArrayPushStack;
			} foreach _surrounding_buildings;
			
			_spawning_roads = [];
			_roads = _building nearRoads 400;
			{
				if ((_x distance _building) > 300) then {
					_spawning_roads set [count _spawning_roads, getPos _x];
				};
			} foreach _roads;
			
		};
		
		// If players are present in the surroundings of the building, we start the attacks.
		if (_players_near_building_updated && _attackers > 0) then {
			if (_enemy_count < _minimum_count) then {
				_grp_cnt = (_grp_cnt + 1);
				_grp_cnt = _grp_cnt min 3;
				if (_attackers < _grp_cnt) then { _grp_cnt = _attackers; };
				
				for [{_i = 0},{_i < _grp_cnt},{_i = _i + 1}] do {
					if (random(1) > 0.9 && (call XPlayersNumber) > 0) then {
						_i_tries = 20;
						_pos = [];
						while { count _pos <= 0 && _i_tries > 0 } do {
							_pos = (_spawning_roads call XfRandomArrayVal);
							if (X_MP) then {
								{
									if (isPlayer _x) then {
										if (([_x, _pos] call XfDistTo) < 150) exitWith {_pos = [] };
									};
								} foreach playableUnits;
							} else {
								if (([player, _pos] call XfDistTo) < 150) exitWith {_pos = [] };
							};
							_i_tries = _i_tries - 1;
						};
						if (count _pos > 0) then {
							_grpVehicle = [d_enemy_side,[_pos,50],[],XF_VEHICLE_TYPES_LIGHTWHEEL,false,"", false] call XfMissionCreateVehicleGroup;
							_grpVehicle allowFleeing 0;
							_grpVehicle setBehaviour "COMBAT";
							_grpVehicle setCombatMode "RED";
							_grpVehicle setSpeedMode "FULL";
							_grpVehicle addWaypoint [(getPos _building),0];
							[_grpVehicle, _building] call _fnc_checkgroup;
							(leader _grpVehicle) doMove (getPos _building);
						};
					} else {
						_i_tries = 20;
						_pos = [];
						while { count _pos <= 0 && _i_tries > 0 } do {
							_pos = (_spawning_positions call XfRandomArrayVal);
							if (X_MP) then {
								{
									if (isPlayer _x) then {
										if (([_x, _pos] call XfDistTo) < 40) exitWith {_pos = [] };
									};
								} foreach playableUnits;
							} else {
								if (([player, _pos] call XfDistTo) < 40) exitWith {_pos = [] };
							};
							_i_tries = _i_tries - 1;
						};
						if (count _pos > 0) then {
							// [false,[format["grp_reinf_%1",_i],_pos, "ICON", "ColorBlue", [0.5,0.5],"",0,"mil_dot","",0.6]] call XfMissionMarker;
							_grpSoldiers = [d_enemy_side,[(getMarkerPos "respawn_east"),15],[],floor(random(5)),false,"","FORM",false] call XfMissionCreateFootmenGroup;
							{
								_x setVelocity [0,0,0];
								_x setPosASL _pos;
							} foreach (units _grpSoldiers);
							_grpSoldiers allowFleeing 0;
							_grpSoldiers setBehaviour "STEALTH";
							_grpSoldiers setCombatMode "RED";
							_grpSoldiers setSpeedMode "FULL";
							_grpSoldiers addWaypoint [(getPos _building),0];
							[_grpSoldiers, _building] call _fnc_checkgroup;
							(leader _grpSoldiers) doMove (getPos _building);
							diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Generated Group",[_pos, _grpSoldiers], Time];
						};
					};
				};
				[getPos _building, d_enemy_side, _random_town_size + 120, [], 20] call XfMissionConvergeUnits;
			};
		};
		
		if (!_building_destroyed && _attackers <= 0 && _enemy_count <= 0) then {
			["DefendBuilding","", "","",[],"Succeeded"] call XfMissionTask;
			"STR_MF_M_NEWSNETWORK_REPELLED" call XfMissionMessageToAll;
			sleep 30;
			_chapter_succeeded = true;
			DM_Mission_Chapter_CanRun = false;
		};
		
		if (_building_destroyed) then {
			["DefendBuilding","", "","",[],"Failed"] call XfMissionTask;
			"STR_MF_WTH" call XfMissionMessageToAll;
			sleep 30;
			_chapter_succeeded = false;
			DM_Mission_Chapter_CanRun = false;
		};
	};
	
	if (DM_Mission_Mission_CanRun) then {
		if (_chapter_succeeded) then {
			call XfMissionChapterSuccess;
		} else {
			call XfMissionChapterFailure;
		};
	} else {
		diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Mission canceled!"];
	};
	
	_players_found = true;
	_enemy_count = 100;
	While {DM_Mission_Mission_CanRun && _enemy_count > 3 && _players_found} do {
		sleep 5;
		if (X_MP) then {
			_players_found = false;
			{
				if (([(getPos _x), _random_town_pos, 600] call XfPointInCircle) && isplayer _x) exitWith { _players_found = true; };
			}foreach playableUnits;
		} else {
			_players_found = ([(getPos player), _random_town_pos, 600] call XfPointInCircle);
		};
		_enemy_count = (([_random_town_pos,400,d_enemy_side] call XfMissionGetZoneSideCount) select 0);
		if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3: %4: player:%5  enemies:%6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Chapter End Check",_players_found,_enemy_count]; };
	};
	// Just in case a reinforcement is already on the way.
	call XfMissionCancelReinforcement;
	call XfMissionChapterCleanUp;
	DM_Mission_Chapter_Runs = False;
};

XfMissionChapterSetup={
	private ["_random_town","_random_town_pos","_random_town_size","_troops_power","_troops_coeff","_grpSpecOps","_i","_houses","_objects","_surrounding_buildings","_matching_buildings","_building"
		,"_building_array","_i_tries"];
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Starting Initialization"];
	
	_random_town = [];
	_random_town_pos = [];
	_random_town_size = 200;
	_building_array = [];
	_building = objNull;
	_i_tries = 30;
	_surrounding_buildings = [];
	_building_list = [20] call XfBuildingFilteredList;
	_surrounding_list = [-1,1,1] call XfBuildingFilteredList;
	
	while { count _random_town <= 0 && _i_tries > 0 } do {
		// Only big towns
		_random_town = [[XF_MAP_LOCATION_TYPE_TOWN,XF_MAP_LOCATION_TYPE_ISLAND],150] call XfMissionGetRandomSpot;
		_random_town_pos = _random_town select XF_MAP_LOCATION_CENTER;
		_random_town_size = _random_town select XF_MAP_LOCATION_SIZE;
		_building = objNull;
		_matching_buildings = [];
		_surrounding_buildings = [];
		_objects = nearestObjects [_random_town_pos, _building_list, _random_town_size];
		_houses = nearestObjects [_random_town_pos, _surrounding_list, _random_town_size * 2];
		diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup",Format["Exploring %1: %2 buildings and %3 houses", (_random_town select XF_MAP_LOCATION_DISPLAYNAME), count _objects, count _houses]];
		if (isnull _building && (count _objects > 0)) then {
			{
				_surrounding_buildings = [];
				_bld = _x;
				_pos_bld = getPos _bld;
				if (damage _bld < 0.2) then {
					{
						_house = _x;
						if (((_house distance _bld) < 200) && ((_house distance _bld) >= 100)) then {
							_surrounding_buildings set [count _surrounding_buildings, _house];
						};
						
					} foreach _houses;
					if (count _surrounding_buildings > 3) then {
						_matching_buildings set [count _matching_buildings, [_bld, _surrounding_buildings]];
					};
				} else {
					diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup",Format["Ignoring destroyed building in %1", (_random_town select XF_MAP_LOCATION_DISPLAYNAME)]];
				};
			} foreach _objects;
		};
		diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Matching buildings", _matching_buildings];
		if (count _matching_buildings > 0) exitWith {
			_building_array = _matching_buildings call XfRandomArrayVal;
			_building = _building_array select 0;
			_surrounding_buildings = _building_array select 1;
		};
		if (!isnull _building) exitWith {};
		_random_town = [];
		_i_tries = _i_tries - 1;
	};
	if ((count _random_town) <= 0) exitWith {"STR_MF_RANDOMSITEFAILED" call XfMissionMessageToAll; DM_Mission_Mission_CanRun = false; DM_Mission_Chapter_CanRun = false;};
	if (isNull _building) exitWith {"STR_MF_RANDOMBUILDINGFAILED" call XfMissionMessageToAll; DM_Mission_Mission_CanRun = false; DM_Mission_Chapter_CanRun = false;};
	_random_town_name = _random_town select XF_MAP_LOCATION_DISPLAYNAME;
	DM_Chapter_Location = _random_town;
	DM_Chapter_Position = _random_town_pos;
	DM_Target = _building;
	DM_Chapter_Data = _surrounding_buildings;

	// This indicates where the mission takes place
	[_random_town_pos,_random_town_size,_random_town_name] call XfMissionCurrentPosition;
	// We search a spot to place the teleporter which is around the town on a road (to avoid mountains and forests)
	_teleporter = [_random_town_pos] call XfMissionRandomStartTeleporter;
	// If no spot found, we get back an empty position.
	if (count (_teleporter select 0) > 0) then {
		[false,["chapter1_start_position",(_teleporter select 0), "ICON", "ColorBlue", [1,1],"",(_teleporter select 1),"hd_start","",1]] call XfMissionMarker;
	};

	// The marker which indicates the buildings zone
	[false,["chapter1_random_town_zone", _random_town_pos, "ELLIPSE", "ColorRed", [_random_town_size,_random_town_size],"",0,"","BDiagonal",0.5]] call XfMissionMarker;
	[false,["chapter1_building_position",getPos _building, "ICON", "ColorRed", [1,1],"V.N.N.",0,"hd_objective","",0.6]] call XfMissionMarker;
	
	["DefendBuilding","STR_MF_M_NEWSNETWORK_TASK_DEFEND", ["STR_MF_M_NEWSNETWORK_TASK_DEFEND_DESC",_random_town_name],"",[],"Created"] call XfMissionTask;
	
	_amount = round(random(_random_town_size / 14)) + round(_random_town_size / 17);
	[[_random_town_pos,_random_town_size],"CIV",_amount] call XfMissionCivilianSpawn;
};

XfMissionChapterSuccess={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSuccess","Starting"];
	"STR_MF_M_NEWSNETWORK_SUCCESS" call XfMissionMessageToAll;
	DM_Mission_Chapter_Success = 1;
};

XfMissionChapterFailure={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterFailure","Starting"];
	"STR_MF_MISSIONFAILURE1" call XfMissionMessageToAll;
	DM_Mission_Chapter_Success = -1;
};

// Self-explanatory
XfMissionChapterCleanUp={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterCleanUp","Starting"];
	// Giving an empty position places the teleporter back to the hangar, closing the hangar.
	[[],0] call XfMissionPlaceStartTeleporter;
	[] call XfMissionCleanMarkers;
	[] call XfMissionCleanTriggers;
	[] call XfMissionCleanTasks;
};

DM_Mission_Chapter_Compiled = true;